home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- TITLE Sound Blaster Object Module
- SUBTTL Main Program
-
-
- if1
- ifdef small
- %OUT Small Model
- else
- %OUT Large Model
- endif
- endif
-
-
-
- ifdef small
- _TEXT SEGMENT WORD PUBLIC 'CODE'
- _TEXT ENDS
- else
- CTV_TEXT SEGMENT WORD PUBLIC 'CODE'
- CTV_TEXT ENDS
- endif
-
-
- _DATA SEGMENT WORD PUBLIC 'DATA'
- _DATA ENDS
- CONST SEGMENT WORD PUBLIC 'CONST'
- CONST ENDS
- _BSS SEGMENT WORD PUBLIC 'BSS'
- _BSS ENDS
-
-
- DGROUP GROUP CONST, _BSS, _DATA
-
- ifdef small
- ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP
- else
- ASSUME CS: CTV_TEXT, DS: DGROUP, SS: DGROUP
- endif
-
-
- PUBLIC _io_addx, _intr_num, _voice_status
- PUBLIC _ctv_detect, _ctv_speaker, _ctv_output,
- PUBLIC _ctv_halt
- PUBLIC _ctv_pause, _ctv_continue, _ctv_uninstall
- PUBLIC _ctv_card_here
-
-
-
-
- _DATA SEGMENT WORD PUBLIC 'DATA'
-
- ifdef small
- ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP
- else
- ASSUME CS: CTV_TEXT, DS: DGROUP, SS: DGROUP
- endif
-
- _io_addx DW 220H
- _intr_num DB 0
- _voice_status DW 0
-
- ORG_INT_ADDX LABEL DWORD
- ORG_INT2_ADDX LABEL DWORD
- ORG_INT2_OFF DW ?
- ORG_INT2_SEG DW ?
- ORG_INT3_ADDX LABEL DWORD
- ORG_INT3_OFF DW ?
- ORG_INT3_SEG DW ?
- ORG_INT5_ADDX LABEL DWORD
- ORG_INT5_OFF DW ?
- ORG_INT5_SEG DW ?
- ORG_INT7_ADDX LABEL DWORD
- ORG_INT7_OFF DW ?
- ORG_INT7_SEG DW ?
-
-
- ;---------------------
- ; DMA DATA |
- ;---------------------
- DMA_CURRENT_PAGE DB ?
- DMA_CURRENT_ADDX DW ?
- DMA_CURRENT_COUNT DW ?
- PAGE_TO_DMA DB ?
- LEN_L_TO_DMA DW ?
- LEN_H_TO_DMA DW ?
- LAST_DMA_OFFSET DW ?
-
-
- _DATA ENDS
-
-
- ifdef small
- _TEXT SEGMENT WORD PUBLIC 'CODE'
- else
- CTV_TEXT SEGMENT WORD PUBLIC 'CODE'
- endif
-
- SUBTTL DSP module
-
- WAIT_TIME EQU 0200H
- DMA_VOICE_IN EQU 45H
- DMA_VOICE_OUT EQU 49H
-
- DSP_ID_CMD EQU 0E0H
- DSP_VER_CMD EQU 0E1H
- DSP_VI8_CMD EQU 24H
- DSP_VO8_CMD EQU 14H
- DSP_VO2_CMD EQU 17H
- DSP_VO4_CMD EQU 75H
- DSP_VO25_CMD EQU 77H
- DSP_MDAC1_CMD EQU 61H
- DSP_MDAC2_CMD EQU 62H
- DSP_MDAC3_CMD EQU 63H
- DSP_MDAC4_CMD EQU 64H
- DSP_MDAC5_CMD EQU 65H
- DSP_MDAC6_CMD EQU 66H
- DSP_MDAC7_CMD EQU 67H
- DSP_TIME_CMD EQU 40H
- DSP_SILENCE_CMD EQU 80H
- DSP_PAUSE_DMA_CMD EQU 0D0H
- DSP_ONSPK_CMD EQU 0D1H
- DSP_OFFSPK_CMD EQU 0D3H
- DSP_CONT_DMA_CMD EQU 0D4H
- DSP_INTRQ_CMD EQU 0F2H
-
- CMS_TEST_CODE EQU 0C6H
- RESET_TEST_CODE EQU 0AAH
-
- CMS_EXIST EQU 1
- FM_MUSIC_EXIST EQU 2
- CTV_VOICE_EXIST EQU 4
-
- FM_WAIT_TIME EQU 40H
-
-
- WRITE_DSP_TIME PROC
-
- PUSH CX
-
- MOV CX,WAIT_TIME
- MOV AH,AL
-
- WDT10:
- IN AL,DX
- OR AL,AL
- JNS WDT20
-
- LOOP WDT10
-
- STC
- JMP SHORT WDT90
-
- WDT20:
- MOV AL,AH
- OUT DX,AL
- CLC
-
- WDT90:
- POP CX
- RET
-
- WRITE_DSP_TIME ENDP
-
-
-
- READ_DSP_TIME PROC
-
- PUSH CX
- PUSH DX
-
- MOV DX,_io_addx
- ADD DL,0EH
-
- MOV CX,WAIT_TIME
-
- RDT10:
- IN AL,DX
- OR AL,AL
- JS RDT20
-
- LOOP RDT10
- STC
- JMP SHORT RDT90
-
- RDT20:
- SUB DL,4
- IN AL,DX
- CLC
-
- RDT90:
- POP DX
- POP CX
- RET
-
- READ_DSP_TIME ENDP
-
-
- WRITE_DSP PROC
-
- MOV AH,AL
- MOV AL,0F0H
-
- WD10:
- IN AL,DX
- OR AL,AL
- JS WD10
-
- MOV AL,AH
- OUT DX,AL
- RET
-
- WRITE_DSP ENDP
-
-
-
- READ_DSP PROC
-
- PUSH DX
-
- MOV DX,_io_addx
- ADD DL,0EH
- SUB AL,AL
-
- RD10:
- IN AL,DX
- OR AL,AL
- JNS RD10
-
- SUB DL,4
- IN AL,DX
-
- POP DX
- RET
-
- READ_DSP ENDP
-
-
- RESET_DSP PROC
-
- MOV DX,_io_addx
- ADD DL,6
- MOV AL,1
- OUT DX,AL
-
- IN AL,DX
- RDSP05:
- INC AL
- JNZ RDSP05
-
- OUT DX,AL
-
- MOV CL,20H
-
- RDSP10:
- CALL READ_DSP_TIME
- CMP AL,0AAH
- JE RDSP20
-
- DEC CL
- JNZ RDSP10
- MOV AX,2
- JMP SHORT RDSP90
-
- RDSP20:
- SUB AX,AX
-
- RDSP90:
- OR AX,AX
- RET
-
- RESET_DSP ENDP
-
-
- VERIFY_IO_CHK PROC
-
- MOV BX,2
-
- MOV AL,DSP_ID_CMD
- MOV DX,_io_addx
- ADD DX,0CH
- CALL WRITE_DSP_TIME
- JC VIO90
-
- MOV AL,0AAH
- CALL WRITE_DSP_TIME
- JC VIO90
-
- CALL READ_DSP_TIME
- JC VIO90
-
- CMP AL,055H
- JNE VIO90
-
- SUB BX,BX
-
- VIO90:
- MOV AX,BX
- OR AX,AX
- RET
-
- VERIFY_IO_CHK ENDP
-
-
- VERIFY_INTR PROC
-
- MOV AL,2
- MOV DX,OFFSET DUMMY_DMA_INT2
- MOV BX,OFFSET DGROUP:ORG_INT2_ADDX
- CALL SETUP_INTERRUPT
-
- MOV AL,3
- MOV DX,OFFSET DUMMY_DMA_INT3
- MOV BX,OFFSET DGROUP:ORG_INT3_ADDX
- CALL SETUP_INTERRUPT
-
- MOV AL,5
- MOV DX,OFFSET DUMMY_DMA_INT5
- MOV BX,OFFSET DGROUP:ORG_INT5_ADDX
- CALL SETUP_INTERRUPT
-
- MOV AL,7
- MOV DX,OFFSET DUMMY_DMA_INT7
- MOV BX,OFFSET DGROUP:ORG_INT7_ADDX
- CALL SETUP_INTERRUPT
-
- MOV _intr_num,0
-
- MOV DX,_io_addx
- ADD DX,0CH
- MOV AL,DSP_INTRQ_CMD
- CALL WRITE_DSP
-
-
- IN AL,21H
-
- PUSH AX
- AND AL,01010011B
- OUT 21H,AL
-
- SUB AX,AX
- MOV CX,WAIT_TIME*4
-
- VI10:
- CMP _intr_num,0
- JNZ VI90
-
- LOOP VI10
-
- MOV AX,3
-
- VI90:
- POP BX
-
- PUSH AX
-
- MOV AL,BL
- OUT 21H,AL
-
- MOV AL,2
- MOV BX,OFFSET DGROUP:ORG_INT2_ADDX
- CALL RESTORE_INTERRUPT
-
- MOV AL,3
- MOV BX,OFFSET DGROUP:ORG_INT3_ADDX
- CALL RESTORE_INTERRUPT
-
- MOV AL,5
- MOV BX,OFFSET DGROUP:ORG_INT5_ADDX
- CALL RESTORE_INTERRUPT
-
- MOV AL,7
- MOV BX,OFFSET DGROUP:ORG_INT7_ADDX
- CALL RESTORE_INTERRUPT
-
- POP AX
-
- OR AX,AX
- RET
-
- VERIFY_INTR ENDP
-
-
- CHK_DSP_VERSION PROC
-
- MOV AL,DSP_VER_CMD
- MOV DX,_io_addx
- ADD DL,0CH
- CALL WRITE_DSP
- CALL READ_DSP
- MOV AH,AL
- CALL READ_DSP
-
- MOV BX,1
- CMP AX,101H
- JB CDV90
-
- SUB BX,BX
-
- CDV90:
- MOV AX,BX
- OR AX,AX
- RET
-
- CHK_DSP_VERSION ENDP
-
-
-
- PAUSE_DSP_DMA PROC
-
- PUSHF
-
- MOV AH,DSP_PAUSE_DMA_CMD
- MOV BX,OFFSET DGROUP:_voice_status
- SUB CX,CX
- MOV DX,_io_addx
- ADD DL,0CH
-
- PDD10:
- STI ; enable intr. for voice-out intr
- CMP CX,[BX] ; to update voice_status
- JE PDD90
-
- CLI ; disable intr. for following check
- IN AL,DX ; which is timing critical
- OR AL,AL
- JNS PDD10 ; wait for DSP not ready
-
- PDD20:
- IN AL,DX
- OR AL,AL
- JS PDD20 ; wait for DSP ready
-
- MOV AL,AH
- OUT DX,AL ; write pause dma immediately
-
- PDD90:
- POPF
- RET
-
- PAUSE_DSP_DMA ENDP
-
-
- SUBTTL DMA module
-
-
- ;--------------------------------------------
- ; entry: DH = dma mode :
- ; DL = page :
- ; AX = current addx :
- ; CX = current count :
- ;--------------------------------------------
-
- DMA_ADDX_REG EQU 02H
- DMA_COUNT_REG EQU 03H
- DMA_MASK_REG EQU 0AH
- DMA_MODE_REG EQU 0BH
- DMA_FF_REG EQU 0CH
- DMA_PAGE_REG EQU 83H
-
-
-
- PROG_DMA PROC
-
- PUSH BX
-
- MOV BX,AX
-
- MOV AL,5
- OUT DMA_MASK_REG,AL
-
- SUB AL,AL
- OUT DMA_FF_REG,AL
-
- MOV AL,DH
- OUT DMA_MODE_REG,AL
-
- MOV AL,BL
- OUT DMA_ADDX_REG,AL
-
- MOV AL,BH
- OUT DMA_ADDX_REG,AL
-
- MOV AL,CL
- OUT DMA_COUNT_REG,AL
-
- MOV AL,CH
- OUT DMA_COUNT_REG,AL
-
- MOV AL,DL
- OUT DMA_PAGE_REG,AL
-
- MOV AL,1
- OUT DMA_MASK_REG,AL
-
- POP BX
- RET
-
- PROG_DMA ENDP
-
-
- CALC_20BIT_ADDX PROC
-
- PUSH CX
-
- MOV CL,4
- ROL DX,CL
- MOV CX,DX
- AND DX,0FH
- AND CX,0FFF0H
- ADD AX,CX
- ADC DX,0
-
- POP CX
- RET
-
- CALC_20BIT_ADDX ENDP
-
-
- ;-------------------------------------------------
- ; entry: AL = INTERRUPT NUM |
- ; DX = new vector ofs, seg is alway CS |
- ; BX = offset of store buffer :
- ;-------------------------------------------------
- SETUP_INTERRUPT PROC
-
- PUSHF
- PUSH BX
- PUSH CX
- PUSH DX
-
- CLI
-
- MOV CL,AL ; preserve interrupt number for use
-
- ADD AL,8 ; calculate interrupt vector addx
- CBW
- SHL AL,1
- SHL AL,1
- MOV DI,AX
-
- PUSH ES ; setup and preserve interrupt
- SUB AX,AX
- MOV ES,AX
- MOV AX,ES:[DI]
- MOV [BX],AX
- MOV ES:[DI],DX
-
- MOV AX,ES:[DI+2]
- MOV [BX+2],AX
- MOV ES:[DI+2],CS
-
- POP ES
-
- POP DX
- POP CX
- POP BX
- POPF
- RET
-
- SETUP_INTERRUPT ENDP
-
-
- ;-------------------------------------------------
- ; entry: AL = INTERRUPT NUM |
- ; BX = offset to stored addx |
- ;-------------------------------------------------
- RESTORE_INTERRUPT PROC
-
- PUSHF
-
- CLI
-
- MOV CL,AL
-
- ADD AL,8 ; calculate interrupt vector addx
- CBW
- SHL AL,1
- SHL AL,1
- MOV DI,AX
-
- PUSH ES ; restore interrupt vector
- SUB AX,AX
- MOV ES,AX
- MOV AX,[BX]
- MOV ES:[DI],AX
-
- MOV AX,[BX+2]
- MOV ES:[DI+2],AX
-
- POP ES
-
- MOV AH,1
- SHL AH,CL
-
- IN AL,21H
- OR AL,AH
- OUT 21H,AL
-
- POPF
- RET
-
- RESTORE_INTERRUPT ENDP
-
-
- DUMMY_DMA_INT2 PROC FAR
-
- PUSH DX
- MOV DL,2
- JMP SHORT DUMMY_DMA_ISR
-
- DUMMY_DMA_INT2 ENDP
-
-
- DUMMY_DMA_INT3 PROC FAR
-
- PUSH DX
- MOV DL,3
- JMP SHORT DUMMY_DMA_ISR
-
- DUMMY_DMA_INT3 ENDP
-
-
- DUMMY_DMA_INT5 PROC FAR
-
- PUSH DX
- MOV DL,5
- JMP SHORT DUMMY_DMA_ISR
-
- DUMMY_DMA_INT5 ENDP
-
-
- DUMMY_DMA_INT7 PROC FAR
-
- PUSH DX
- MOV DL,7
-
- DUMMY_DMA_ISR:
-
- PUSH DS
- PUSH AX
-
- MOV AX,DGROUP
- MOV DS,AX
-
- MOV _intr_num,DL
-
- MOV DX,_io_addx
- ADD DX,0EH
- IN AL,DX
-
- MOV AL,20H
- OUT 20H,AL
-
- POP AX
- POP DS
- POP DX
- IRET
-
- DUMMY_DMA_INT7 ENDP
-
-
-
- DMA_OUT_INTR PROC
-
- PUSH DS
- PUSH ES
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH DI
- PUSH SI
- PUSH BP
-
- CLD
- MOV AX,DGROUP
- MOV DS,AX
- MOV ES,AX
-
- MOV DX,_io_addx
- ADD DL,0EH
- IN AL,DX
-
- MOV AX,LEN_L_TO_DMA
- OR AX,AX
- JNZ VO_INT10
-
- CALL END_DMA_TRANSFER
-
- JMP SHORT VO_INT90
-
- VO_INT10:
- CALL DMA_OUT_TRANSFER
-
- VO_INT90:
- MOV AL,20H
- OUT 20H,AL
-
- POP BP
- POP SI
- POP DI
- POP DX
- POP CX
- POP BX
- POP AX
- POP ES
- POP DS
- IRET
-
- DMA_OUT_INTR ENDP
-
-
-
- DMA_OUT_TRANSFER PROC
-
- MOV CX,0FFFFH ; get current page end address
-
- CMP PAGE_TO_DMA,0 ; last page to dma ?
- JNZ DOT10 ; no, skip
-
- INC PAGE_TO_DMA
- MOV CX,LAST_DMA_OFFSET ; get end addx
-
- DOT10:
- SUB CX,DMA_CURRENT_ADDX ; calcutate current page addx
- MOV DMA_CURRENT_COUNT,CX
- INC CX
- JZ DOT20
-
- SUB LEN_L_TO_DMA,CX
- SBB LEN_H_TO_DMA,0
- JMP SHORT DOT30
-
- DOT20:
- DEC LEN_H_TO_DMA
-
- DOT30:
- MOV DH,DMA_VOICE_OUT
- MOV DL,DMA_CURRENT_PAGE
- MOV AX,DMA_CURRENT_ADDX
- MOV CX,DMA_CURRENT_COUNT
- CALL PROG_DMA
-
- DEC PAGE_TO_DMA
- INC DMA_CURRENT_PAGE
- MOV DMA_CURRENT_ADDX,0
-
- MOV CX,DMA_CURRENT_COUNT
-
- MOV DX,_io_addx
- ADD DL,0CH
-
- MOV AL,DSP_VO8_CMD
- CALL WRITE_DSP
-
- MOV AL,CL
- CALL WRITE_DSP
-
- MOV AL,CH
- CALL WRITE_DSP
-
- DOT90:
- RET
-
- DMA_OUT_TRANSFER ENDP
-
-
-
- END_DMA_TRANSFER PROC
-
- MOV AL,5
- OUT DMA_MASK_REG,AL
-
- MOV CL,_intr_num
- MOV AH,1
- SHL AH,CL
- IN AL,21H
- OR AL,AH
- OUT 21H,AL
-
- MOV AL,_intr_num
- MOV BX,OFFSET DGROUP:ORG_INT_ADDX
- CALL RESTORE_INTERRUPT
-
- MOV _voice_status,0
-
- MOV DX,_io_addx
- ADD DL,0EH
- IN AL,DX
-
- RET
-
- END_DMA_TRANSFER ENDP
-
-
- ;---------------------------------------
- ; WAIT_FM_STATUS :
- ; entry: AL = status to wait :
- ; 3 msb is concern :
- ; exit : AX destroy :
- ; carry set for fail :
- ; carry clr for pass :
- ;---------------------------------------
- WAIT_FM_STATUS PROC
-
- PUSH CX
- PUSH DX
-
- MOV CX,FM_WAIT_TIME
-
- MOV AH,AL
- AND AH,0E0H ; only 3 msb are FM status
- MOV DX,_io_addx
- ADD DL,8
-
- WFS10:
- IN AL,DX
- AND AL,0E0H
- CMP AH,AL
- JE WFS20
-
- LOOP WFS10
-
- STC
- JMP SHORT WFS90
-
- WFS20:
- CLC
-
- WFS90:
- POP DX
- POP CX
- RET
-
- WAIT_FM_STATUS ENDP
-
-
- ;---------------------------------------
- ; WRITE_FM :
- ; entry: AH = data value :
- ; AL = addx value :
- ; exit : AX destroy :
- ; DX destroy :
- ;---------------------------------------
- WRITE_FM PROC
-
- MOV DX,_io_addx
- ADD DL,8
- OUT DX,AL
- CALL FM_DELAY
- MOV AL,AH
- INC DX
- OUT DX,AL
- CALL FM_DELAY
- RET
-
- WRITE_FM ENDP
-
-
- FM_DELAY PROC
-
- PUSH AX
- PUSH DX
-
- MOV DX,_io_addx
- ADD DL,8
-
- IN AL,DX
- IN AL,DX
- IN AL,DX
- IN AL,DX
- IN AL,DX
-
- POP DX
- POP AX
-
- RET
-
- FM_DELAY ENDP
-
-
-
-
-
- ifdef small
- _ctv_detect PROC
- else
- _ctv_detect PROC FAR
- endif
- PUSH DS
- PUSH ES
- PUSH DI
- PUSH SI
-
- MOV AX,DGROUP
- MOV DS,AX
- MOV ES,AX
-
- CALL RESET_DSP
- JNZ ID90
-
- CALL VERIFY_IO_CHK
- JNZ ID90
-
- CALL CHK_DSP_VERSION
- JNZ ID90
-
- CALL VERIFY_INTR
- JNZ ID90
-
- MOV AL,1 ; on speaker
- CALL ON_OFF_SPEAKER
-
- SUB AX,AX
-
- ID90:
- POP SI
- POP DI
- POP ES
- POP DS
- RET
-
- _ctv_detect ENDP
-
-
- SPK_STK STRUC
-
- ifdef small
- DW ?
- else
- DD ?
- endif
-
- DW ?
- SPK_FLAG DW ?
-
- SPK_STK ENDS
-
-
- ifdef small
- _ctv_speaker PROC
- else
- _ctv_speaker PROC FAR
- endif
-
- PUSH BP
- MOV BP,SP
-
- PUSH DS
-
- MOV AX,DGROUP
- MOV DS,AX
-
- MOV AX,[BP+SPK_FLAG]
- CALL ON_OFF_SPEAKER
-
-
- POP DS
-
- POP BP
- RET
-
- _ctv_speaker ENDP
-
-
- ON_OFF_SPEAKER PROC
-
-
- MOV DX,_io_addx
- ADD DX,0CH
-
- MOV AH,DSP_ONSPK_CMD
- OR AL,AL
- JNZ OOS10
-
- MOV AH,DSP_OFFSPK_CMD
-
- OOS10:
- MOV AL,AH
- CALL WRITE_DSP
-
- SUB AX,AX ; inidcate no error
- RET
-
- ON_OFF_SPEAKER ENDP
-
-
-
- OUT_STK STRUC
-
- ifdef small
- DW ? ; one word ret addx
- else
- DD ? ; double word ret addx
- endif
- DW ?
- BUF_OFF DW ?
- BUF_SEG DW ?
- COUNT DW ?
- SAMPLING DW ?
-
- OUT_STK ENDS
-
-
- ifdef small
- _ctv_output PROC
- else
- _ctv_output PROC FAR
- endif
-
- PUSH BP
- MOV BP,SP
-
- PUSH DS
- PUSH ES
- PUSH DI
- PUSH SI
-
- MOV AX,DGROUP
- MOV DS,AX
- MOV ES,AX
-
- CMP _voice_status,0
- JZ OV10
-
- MOV AX,1
- JMP OV90
-
- OV10:
- MOV _voice_status,1
-
- MOV DX,_io_addx
- ADD DL,0CH
-
- MOV DX,0FH ; calculate sampling rate value for
- MOV AX,4240H ; DSP
- MOV CX,[BP+SAMPLING]
- DIV CX
-
- MOV CL,AL
- NEG CL
-
- MOV DX,_io_addx
- ADD DL,0CH
- MOV AL,DSP_TIME_CMD
- CALL WRITE_DSP
-
- MOV AL,CL
- CALL WRITE_DSP
-
- MOV AL,_intr_num
- MOV DX,OFFSET DMA_OUT_INTR
- MOV BX,OFFSET DGROUP:ORG_INT_ADDX
- CALL SETUP_INTERRUPT
-
- MOV CL,_intr_num
- MOV AH,1
- SHL AH,CL
- NOT AH
- IN AL,21H
- AND AL,AH
- OUT 21H,AL
-
- MOV DX,[BP+BUF_SEG]
- MOV AX,[BP+BUF_OFF]
- CALL CALC_20BIT_ADDX
-
- MOV DMA_CURRENT_PAGE,DL
- MOV DMA_CURRENT_ADDX,AX
-
- MOV CX,[BP+COUNT]
- MOV LEN_L_TO_DMA,CX
- MOV LEN_H_TO_DMA,0
-
- ADD AX,[BP+COUNT]
- ADC DL,0
- SUB AX,1
- SBB DL,0
-
- MOV LAST_DMA_OFFSET,AX
- SUB DL,DMA_CURRENT_PAGE
- MOV PAGE_TO_DMA,DL
-
- CALL DMA_OUT_TRANSFER
-
- SUB AX,AX
-
- OV90:
- POP SI
- POP DI
- POP ES
- POP DS
-
- POP BP
- RET
-
- _ctv_output ENDP
-
-
- ifdef small
- _ctv_halt PROC
- else
- _ctv_halt PROC FAR
- endif
-
- PUSH DS
- PUSH ES
- PUSH DI
- PUSH SI
-
- MOV AX,DGROUP
- MOV DS,AX
- MOV ES,AX
-
- MOV AX,1
-
- CMP _voice_status,0
- JZ TVP90
-
- CALL PAUSE_DSP_DMA
- CALL END_DMA_TRANSFER
-
- SUB AX,AX
-
- TVP90:
- POP SI
- POP DI
- POP ES
- POP DS
- RET
-
- _ctv_halt ENDP
-
-
- ifdef small
- _ctv_pause PROC
- else
- _ctv_pause PROC FAR
- endif
-
- PUSH DS
- PUSH ES
- PUSH DI
- PUSH SI
-
- MOV AX,DGROUP
- MOV DS,AX
- MOV ES,AX
-
- MOV AX,1
-
- CMP _voice_status,1
- JNE PV90
-
- CALL PAUSE_DSP_DMA
- SUB AX,AX
-
- PV90:
- POP SI
- POP DI
- POP ES
- POP DS
- RET
-
- _ctv_pause ENDP
-
-
-
- ifdef small
- _ctv_continue PROC
- else
- _ctv_continue PROC FAR
- endif
-
- PUSH DS
- PUSH ES
- PUSH DI
- PUSH SI
-
- MOV AX,DGROUP
- MOV DS,AX
- MOV ES,AX
-
- MOV AX,1
-
- CMP _voice_status,1
- JNE CV90
-
- MOV DX,_io_addx
- ADD DL,0CH
-
- MOV AL,DSP_CONT_DMA_CMD
- CALL WRITE_DSP
- SUB AX,AX
-
- CV90:
- POP SI
- POP DI
- POP ES
- POP DS
- RET
-
- _ctv_continue ENDP
-
-
- ifdef small
- _ctv_uninstall PROC
- else
- _ctv_uninstall PROC FAR
- endif
-
- PUSH DS
- PUSH ES
- PUSH DI
- PUSH SI
-
- MOV AX,DGROUP
- MOV DS,AX
- MOV ES,AX
-
- CMP _voice_status,0
- JZ UI90
-
- CALL PAUSE_DSP_DMA
- CALL END_DMA_TRANSFER
-
-
- UI90:
- SUB AL,AL
- CALL ON_OFF_SPEAKER
-
- SUB AX,AX
-
- POP SI
- POP DI
- POP ES
- POP DS
- RET
-
- _ctv_uninstall ENDP
-
-
- ;-----------------------------------------------------------
- ; usage: :
- ; unint ctv_card_here() :
- ; description: :
- ; detect the Game Blaster or Sound Blaster Card and :
- ; the configuration :
- ; entry: :
- ; the global i/o addx, ct_io_addx must set to a default :
- ; value, 2x0H, before call. :
- ; exit: :
- ; High Byte = 0 :
- ; Low Byte format - :
- ; 0000 0001 : C/MS music exists :
- ; 0000 0010 : FM music exists :
- ; 0000 0100 : CTV Voice exists :
- ;-----------------------------------------------------------
-
-
- ifdef small
- _ctv_card_here PROC near
- else
- _ctv_card_here PROC far
- endif
-
-
- PUSH DS ; for multi data model, set DS to
- MOV AX,DGROUP ; DGROUP segment
- MOV DS,AX
-
- SUB BX,BX ; assume Creative Card doesn't exist,
- ; return 0
- ;-----------------------------
- ; detect Game Blaster :
- ;-----------------------------
-
- MOV DX,_io_addx ; get default i/o addx
- ADD DL,6 ; write the test code to
- MOV AL,CMS_TEST_CODE ; output port 2x6H
- OUT DX,AL ; ...
- SUB AL,AL
- ADD DL,4 ; read the data back from
- OUT DX,AL
- IN AL,DX ; input port 2xAH
- CMP AL,CMS_TEST_CODE ; the same data ?
- JNE CARD10 ; no, try Sound Blaster Card
-
- SUB DL,4 ; to ensure, try inverse data
- MOV AL,NOT CMS_TEST_CODE ; output port 2x6H
- OUT DX,AL ; ...
- SUB AL,AL
- ADD DL,4 ; read the data back from
- OUT DX,AL
- IN AL,DX ; input port 2xAH
- CMP AL,NOT CMS_TEST_CODE ; the same data ?
- JNE CARD10 ; no, try Sound Blaster Card
-
- MOV BX,CMS_EXIST
- JMP SHORT CARD50
-
- ;--------------------------------------
- ; detect the Sound Blaster Card :
- ;--------------------------------------
- CARD10:
- CALL RESET_DSP
- JNZ CARD50
-
- CARD40:
- MOV DX,_io_addx
- ADD DL,0CH
-
- MOV AL,DSP_ID_CMD
- CALL WRITE_DSP_TIME
- JC CARD50
-
- MOV AL,CMS_TEST_CODE
- CALL WRITE_DSP_TIME
- JC CARD50
-
- CALL READ_DSP_TIME
- JC CARD50
-
- CMP AL,NOT CMS_TEST_CODE
- JNE CARD50
-
- MOV BX,CMS_EXIST + CTV_VOICE_EXIST
-
-
- ;-----------------------------
- ; detect the FM Music :
- ;-----------------------------
- CARD50:
- MOV AX,0001H ; reset the FM chip
- CALL WRITE_FM
-
- MOV AX,6004H ; mask of timer 1 & 2
- CALL WRITE_FM
-
- MOV AX,8004H ; reset irq and both timer flags
- CALL WRITE_FM
-
- MOV AL,0 ; read for 3 msb clear
- CALL WAIT_FM_STATUS
- JC CARD90
-
- MOV AX,0FF02H ; write timer 1 count
- CALL WRITE_FM
-
- MOV AX,2104H ; start timer 1
- CALL WRITE_FM
-
- MOV AL,0C0H ; wait for irq and timer 1 end
- CALL WAIT_FM_STATUS
- JC CARD90
-
- MOV AX,6004H ; mask of timer 1 & 2
- CALL WRITE_FM
-
- MOV AX,8004H ; reset irq and both timer flags
- CALL WRITE_FM
-
- ADD BX,FM_MUSIC_EXIST
-
- CARD90:
- MOV AX,BX
-
- POP DS
- RET
-
- _ctv_card_here ENDP
-
- ifdef small
-
- _TEXT ENDS
- else
- CTV_TEXT ENDS
- endif
- END
-
-
-
-